#include <iostream>
#include <pthread.h>
#include <vector>
#include <unistd.h>
#include <ctime>
#include <cstring>
#include "blockqueue.hpp"
#include "Task.hpp"

using namespace std;

#define NUM 5

const char *option = "+-*/%";

void *Consumer(void *args)
{
  BlockQueue<Task> *bq = static_cast<BlockQueue<Task> *>(args);
  while (true)
  {
    Task res = bq->pop();
    res.run();

    printf("%s\n", res.getResult().c_str());
  }
}

void *Productor(void *args)
{
  BlockQueue<Task> *bq = static_cast<BlockQueue<Task> *>(args);
  while (true)
  {
    int len = strlen(option);
    int data1 = rand() % 100;
    usleep(1000);
    int data2 = rand() % 100;
    usleep(1000);
    int op = rand() % len;

    Task t(data1, data2, option[op]);
    printf("%s\n", t.getTask().c_str());
    bq->push(t);

    // sleep(1);
    // usleep(10000);
  }
}

int main()
{
  srand(time(nullptr));
  BlockQueue<Task> *bq = new BlockQueue<Task>();

  pthread_t c[5], p[3];
  for (int i = 0; i < 5; i++)
  {
    pthread_create(c + i, nullptr, Consumer, bq);
  }
  for (int i = 0; i < 3; i++)
  {
    pthread_create(p + i, nullptr, Productor, bq);
  }

  // 线程等待
  for (int i = 0; i < 5; i++)
  {
    pthread_join(c[i], nullptr);
  }
  for (int i = 0; i < 3; i++)
  {
    pthread_join(p[i], nullptr);
  }

  return 0;
}

// void *Consumer(void *args)
// {
//   BlockQueue<int> *bq = static_cast<BlockQueue<int> *>(args);
//   while (true)
//   {
//     int data = bq->pop();
//     // cout << "消费了一个数据" << ", data: " << data << endl;
//     printf("消费了一个数据, data: %d\n", data);
//     sleep(1);
//   }
// }

// void *Productor(void *args)
// {
//   BlockQueue<int> *bq = static_cast<BlockQueue<int> *>(args);
//   int data = 0;
//   while (true)
//   {
//     data++;
//     bq->push(data);
//     // cout << "生产了一个任务" << endl;
//     printf("生产了一个任务, data: %d\n", data);
//     // sleep(1);
//   }
// }

// int main()
// {
//   BlockQueue<int> *bq = new BlockQueue<int>();

//   pthread_t c, p;
//   pthread_create(&c, nullptr, Consumer, bq);
//   pthread_create(&p, nullptr, Productor, bq);

//   // 线程等待
//   pthread_join(c, nullptr);
//   pthread_join(p, nullptr);

//   return 0;
// }